﻿using System;
using System.Collections.Generic;
using System.Text;
using Osteox.ManagedCv;

namespace drawing
{
    class Program
    {
        const int NUMBER = 100;
        const int DELAY = 5;
        const string wndname = "Drawing Demo";

        static Scalar random_color(ref Rng rng)
        {
            uint icolor = ManagedCvInvoke.RandInt(ref rng);
            return ManagedCvInvoke.Rgb(icolor & 255, (icolor >> 8) & 255, (icolor >> 16) & 255);
        }

        static void Main(string[] args)
        {
            CvException.TurnRaiseException(true);

            LineTypeFlag line_type = LineTypeFlag.AA; // change it to 8 to see non-antialiased graphics
            int i;
            Point2D32s pt1 = new Point2D32s();
            Point2D32s pt2 = new Point2D32s();
            double angle;
            Size2D32s sz = new Size2D32s();
            Point2D32s[] ptt = new Point2D32s[6];
            int[] arr = new int[2];
            ManagedFont font = new ManagedFont();
            Rng rng;
            int width = 1000, height = 700;
            int width3 = width * 3, height3 = height * 3;
            Size2D32s text_size = new Size2D32s();
            int ymin = 0;
            // Load the source image
            ManagedImage image = new ManagedImage(new Size2D32s(width, height), PixelDepth.Depth8U, 3);
            ManagedImage image2;

            // Create a window
            ManagedCvInvoke.NamedWindow(wndname, WindowMode.Autosize);
            ManagedCvInvoke.Zero(image);
            ManagedCvInvoke.ShowImage(wndname, image);
            ManagedCvInvoke.WaitKey(DELAY);

            rng = ManagedCvInvoke.RNG(-1);
            //pt[0] = &(ptt[0]);
            //pt[1] = &(ptt[3]);

            arr[0] = 3;
            arr[1] = 3;
            for (i = 0; i < NUMBER; i++)
            {
                pt1.X = (int)(ManagedCvInvoke.RandInt(ref rng) % width3) - width;
                pt1.Y = (int)(ManagedCvInvoke.RandInt(ref rng) % height3) - height;
                pt2.X = (int)(ManagedCvInvoke.RandInt(ref rng) % width3) - width;
                pt2.Y = (int)(ManagedCvInvoke.RandInt(ref rng) % height3) - height;

                ManagedCvInvoke.Line(image, pt1, pt2, random_color(ref rng), (int)(ManagedCvInvoke.RandInt(ref rng) % 10), line_type, 0);
                ManagedCvInvoke.ShowImage(wndname, image);
                if (ManagedCvInvoke.WaitKey(DELAY) >= 0) return;
            }

            for (i = 0; i < NUMBER; i++)
            {
                pt1.X = (int)(ManagedCvInvoke.RandInt(ref rng) % width3) - width;
                pt1.Y = (int)(ManagedCvInvoke.RandInt(ref rng) % height3) - height;
                pt2.X = (int)(ManagedCvInvoke.RandInt(ref rng) % width3) - width;
                pt2.Y = (int)(ManagedCvInvoke.RandInt(ref rng) % height3) - height;

                ManagedCvInvoke.Rectangle(image, pt1, pt2, random_color(ref rng), (int)(ManagedCvInvoke.RandInt(ref rng) % 10 - 1), line_type, 0);
                ManagedCvInvoke.ShowImage(wndname, image);
                if (ManagedCvInvoke.WaitKey(DELAY) >= 0) return;
            }

            for (i = 0; i < NUMBER; i++)
            {
                pt1.X = (int)(ManagedCvInvoke.RandInt(ref rng) % width3) - width;
                pt1.Y = (int)(ManagedCvInvoke.RandInt(ref rng) % height3) - height;
                sz.Width = (int)(ManagedCvInvoke.RandInt(ref rng) % 200);
                sz.Height = (int)(ManagedCvInvoke.RandInt(ref rng) % 200);
                angle = (ManagedCvInvoke.RandInt(ref rng) % 1000) * 0.180;

                ManagedCvInvoke.Ellipse(image, pt1, sz, angle, angle - 100, angle + 200,
                          random_color(ref rng), (int)(ManagedCvInvoke.RandInt(ref rng) % 10 - 1), line_type, 0);
                ManagedCvInvoke.ShowImage(wndname, image);
                if (ManagedCvInvoke.WaitKey(DELAY) >= 0) return;
            }

            for (i = 0; i < NUMBER; i++)
            {
                ptt[0] = new Point2D32s(
                    (int)(ManagedCvInvoke.RandInt(ref rng) % width3) - width,
                    (int)(ManagedCvInvoke.RandInt(ref rng) % height3) - height);
                ptt[1] = new Point2D32s(
                    (int)(ManagedCvInvoke.RandInt(ref rng) % width3) - width,
                    (int)(ManagedCvInvoke.RandInt(ref rng) % height3) - height);
                ptt[2] = new Point2D32s(
                    (int)(ManagedCvInvoke.RandInt(ref rng) % width3) - width,
                    (int)(ManagedCvInvoke.RandInt(ref rng) % height3) - height);
                ptt[3] = new Point2D32s(
                    (int)(ManagedCvInvoke.RandInt(ref rng) % width3) - width,
                    (int)(ManagedCvInvoke.RandInt(ref rng) % height3) - height);
                ptt[4] = new Point2D32s(
                    (int)(ManagedCvInvoke.RandInt(ref rng) % width3) - width,
                    (int)(ManagedCvInvoke.RandInt(ref rng) % height3) - height);
                ptt[5] = new Point2D32s(
                    (int)(ManagedCvInvoke.RandInt(ref rng) % width3) - width,
                    (int)(ManagedCvInvoke.RandInt(ref rng) % height3) - height);

                Point2D32s[][] pt = new Point2D32s[2][];
                pt[0] = new Point2D32s[] { ptt[0], ptt[1], ptt[2] };
                pt[1] = new Point2D32s[] { ptt[3], ptt[4], ptt[5] };

                ManagedCvInvoke.PolyLine(image, pt, arr, 2, true, random_color(ref rng), (int)(ManagedCvInvoke.RandInt(ref rng) % 10), line_type, 0);
                ManagedCvInvoke.ShowImage(wndname, image);
                if (ManagedCvInvoke.WaitKey(DELAY) >= 0) return;
            }

            for (i = 0; i < NUMBER; i++)
            {
                ptt[0] = new Point2D32s(
                    (int)(ManagedCvInvoke.RandInt(ref rng) % width3) - width,
                    (int)(ManagedCvInvoke.RandInt(ref rng) % height3) - height);
                ptt[1] = new Point2D32s(
                    (int)(ManagedCvInvoke.RandInt(ref rng) % width3) - width,
                    (int)(ManagedCvInvoke.RandInt(ref rng) % height3) - height);
                ptt[2] = new Point2D32s(
                    (int)(ManagedCvInvoke.RandInt(ref rng) % width3) - width,
                    (int)(ManagedCvInvoke.RandInt(ref rng) % height3) - height);
                ptt[3] = new Point2D32s(
                    (int)(ManagedCvInvoke.RandInt(ref rng) % width3) - width,
                    (int)(ManagedCvInvoke.RandInt(ref rng) % height3) - height);
                ptt[4] = new Point2D32s(
                    (int)(ManagedCvInvoke.RandInt(ref rng) % width3) - width,
                    (int)(ManagedCvInvoke.RandInt(ref rng) % height3) - height);
                ptt[5] = new Point2D32s(
                    (int)(ManagedCvInvoke.RandInt(ref rng) % width3) - width,
                    (int)(ManagedCvInvoke.RandInt(ref rng) % height3) - height);

                Point2D32s[][] pt = new Point2D32s[2][];
                pt[0] = new Point2D32s[] { ptt[0], ptt[1], ptt[2] };
                pt[1] = new Point2D32s[] { ptt[3], ptt[4], ptt[5] };

                ManagedCvInvoke.FillPoly(image, pt, arr, 2, random_color(ref rng), line_type, 0);
                ManagedCvInvoke.ShowImage(wndname, image);
                if (ManagedCvInvoke.WaitKey(DELAY) >= 0) return;
            }

            for (i = 0; i < NUMBER; i++)
            {
                pt1.X = (int)(ManagedCvInvoke.RandInt(ref rng) % width3) - width;
                pt1.Y = (int)(ManagedCvInvoke.RandInt(ref rng) % height3) - height;

                ManagedCvInvoke.Circle(image, pt1, (int)(ManagedCvInvoke.RandInt(ref rng) % 300), random_color(ref rng),
                          (int)(ManagedCvInvoke.RandInt(ref rng) % 10 - 1), line_type, 0);
                ManagedCvInvoke.ShowImage(wndname, image);
                if (ManagedCvInvoke.WaitKey(DELAY) >= 0) return;
            }

            for (i = 1; i < NUMBER; i++)
            {
                pt1.X = (int)(ManagedCvInvoke.RandInt(ref rng) % width3) - width;
                pt1.Y = (int)(ManagedCvInvoke.RandInt(ref rng) % height3) - height;

                ManagedCvInvoke.InitFont(ref font, (FontFlag)(ManagedCvInvoke.RandInt(ref rng) % 8),
                            (ManagedCvInvoke.RandInt(ref rng) % 100) * 0.05 + 0.1, 
                            (ManagedCvInvoke.RandInt(ref rng) % 100) * 0.05 + 0.1,
                            (ManagedCvInvoke.RandInt(ref rng) % 5) * 0.1, 
                            ManagedCvInvoke.Round(ManagedCvInvoke.RandInt(ref rng) % 10), line_type);

                ManagedCvInvoke.PutText(image, "Testing text rendering!", pt1, font, random_color(ref rng));
                ManagedCvInvoke.ShowImage(wndname, image);
                if (ManagedCvInvoke.WaitKey(DELAY) >= 0) return;
            }

            ManagedCvInvoke.InitFont(ref font, FontFlag.HersheyComplex, 3, 3, 0.0, 5, line_type);

            ManagedCvInvoke.GetTextSize("ManagedCv forever!", font, out text_size, out ymin);

            pt1.X = (width - text_size.Width) / 2;
            pt1.Y = (height + text_size.Height) / 2;
            image2 = ManagedCvInvoke.CloneImage(image);

            for (i = 0; i < 255; i++)
            {
                ManagedCvInvoke.SubS(image2, ManagedCvInvoke.ScalarAll(i), image);
                ManagedCvInvoke.PutText(image, "ManagedCv forever!", pt1, font, ManagedCvInvoke.Rgb(255, i, i));
                ManagedCvInvoke.ShowImage(wndname, image);
                if (ManagedCvInvoke.WaitKey(DELAY) >= 0) return;
            }

            // Wait for a key stroke; the same function arranges events processing
            ManagedCvInvoke.WaitKey(0);
        }
    }
}
